﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MonoDevelop.Ide.Gui.Content;
using MonoDevelop.Projects.Dom;
using MonoDevelop.Projects.Dom.Parser;
using Mono.TextEditor;
using MonoDevelop.Projects.Dom.Output;
using MonoDevelop.Ide;

namespace Coq.MonoDevelop
{
    class CoqResolverProvider : ITextEditorResolverProvider
    {
        public class CoqResolveResult : ResolveResult
        {
            public string Tip { get; set; }

            public CoqResolveResult(string tip)
            {
                Tip = tip;
                ResolvedExpression = new ExpressionResult("");
            }

            public override IEnumerable<object> CreateResolveResult(ProjectDom dom, IMember callingMember)
            {
                return new List<object>();
            }
        }

        public CoqResolverProvider()
        {
            int i = 0;
        }

        public string CreateTooltip(ProjectDom dom, ICompilationUnit unit, ResolveResult result, string errorInformations, Ambience ambience, Gdk.ModifierType modifierState)
        {
            var cr = result as CoqResolveResult;
            if (cr == null)
                return null;
            var newTip = cr.Tip.TrimEnd(new char[] {'\r', '\n'});
            return newTip;
        }

        public ResolveResult GetLanguageItem(ProjectDom dom, TextEditorData data, int offset, string expression)
        {
            return null;
        }

        private Tuple<int, int> FindEdges(string Text, int offset)
        {
            int s, e;

            e=s=offset;
            while (s > 0 && (Char.IsLetterOrDigit(Text[s]) || Text[s].CompareTo('.') == 0 || Text[s].CompareTo('_') == 0))
                s--;

            while (e < Text.Length && (Char.IsLetterOrDigit(Text[e]) || Text[e].CompareTo('.') == 0 || Text[e].CompareTo('_') == 0))
                e++;

            if (s!=e)
                return new Tuple<int,int>(s,e);

            return null;
        }

        public ResolveResult GetLanguageItem(ProjectDom dom, TextEditorData data, int offset)
        {
            var text = data.Document.Text;
            if (offset >= text.Length || offset < 0)
                return null;

            var range = FindEdges(text, offset);
            if (range == null) 
                return null;

            var ad = IdeApp.Workbench.ActiveDocument;
            if (ad != null && ad.ParsedDocument == null)
                return null;
            
            var pd = ad.ParsedDocument as CoqParsedDocument;
            
            if (pd != null && !pd.HasErrors)
            {
                var r = CoqProcessAgent.Service.CheckMessage(text.Substring(range.Item1, range.Item2 - range.Item1).Trim());
                if (r == null)
                    return null;

                return new CoqResolveResult(r); ;
            }

            return null;            
        }
    }
}
